﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;

using DanielVaughan.Windows;

namespace DanielVaughan.Calcium.Gui
{
	public partial class ShellView
	{
		double marginExpanded;
		double marginContracted = 10;

		void InitializeDimensionDefaults()
		{
			marginExpanded = columnDefinition_Left.MinWidth;
		}

		/* Needs refactoring. */
		#region Region Expansion

		GridLength columnRightWidth = new GridLength(1, GridUnitType.Star);

		GridLength rowBannerHeight = GridLength.Auto;
		GridLength columnLeftWidth = GridLength.Auto;
		GridLength rowStatusHeight = GridLength.Auto;

		void Expander_Banner_ExpandChanged(object sender, RoutedEventArgs e)
		{
			//			AnimateRow(sender, e, rowDefinition_Banner, ref rowBannerHeight, null);
		}

		void Expander_Left_ExpandChanged(object sender, RoutedEventArgs e)
		{
			ColumnExpandChanged(sender, e, columnDefinition_Left, ref columnLeftWidth, gridSplitter_Left);
		}

		void Expander_Right_ExpandChanged(object sender, RoutedEventArgs e)
		{
			ColumnExpandChanged(sender, e, columnDefinition_Right, ref columnRightWidth, gridSplitter_Right);
		}

		/// <summary>Disable the Slider and reset the Height of the status row</summary>
		/// <param name="sender">The expander</param>
		/// <param name="e">The expand or collapsed event</param>
		void Expander_Bottom_ExpandChanged(object sender, RoutedEventArgs e)
		{
			AnimateRow(sender, e, rowDefinition_OutputDisplay, ref rowStatusHeight, gridSplitter_Bottom);
		}

		void ColumnExpandChanged(object sender, RoutedEventArgs e, ColumnDefinition columnDefinition,
			ref GridLength gridLength, GridSplitter gridSplitter)
		{
			if (e.OriginalSource != sender || gridSplitter == null || columnDefinition == null)
			{
				return;
			}

			if (e.RoutedEvent == Expander.CollapsedEvent)
			{
				ContractColumn(columnDefinition, ref gridLength, gridSplitter);
			}
			else
			{
				ExpandColumn(columnDefinition, ref gridLength, gridSplitter);
			}
		}

		void AnimateRow(object sender, RoutedEventArgs e, RowDefinition rowDefinition,
			ref GridLength gridLength, GridSplitter gridSplitter)
		{
			if (e.OriginalSource != sender || rowDefinition == null)
			{
				return;
			}

			if (e.RoutedEvent == Expander.CollapsedEvent)
			{
				ContractRow(rowDefinition, ref gridLength, gridSplitter);
			}
			else
			{
				ExpandRow(rowDefinition, ref gridLength, gridSplitter);
			}
		}

		void ExpandColumn(ColumnDefinition columnDefinition, ref GridLength gridLength, GridSplitter gridSplitter)
		{
			columnDefinition.MinWidth = marginExpanded;

			var animation = new GridLengthAnimation
			{
				From = columnDefinition.Width,
				To = gridLength,
				Duration = new Duration(TimeSpan.FromSeconds(.25)),
				FillBehavior = FillBehavior.Stop
			};
			animation.Completed += ((sender, e) =>
			{
				if (gridSplitter != null)
				{
					gridSplitter.IsEnabled = true;
				}
			});
			columnDefinition.BeginAnimation(ColumnDefinition.WidthProperty, animation);
		}

		void ContractColumn(ColumnDefinition columnDefinition, ref GridLength gridLength, GridSplitter gridSplitter)
		{
			columnDefinition.MinWidth = marginContracted;

			if (gridSplitter != null)
			{
				gridSplitter.IsEnabled = false;
			}
			//border_Left.Margin = new Thickness(0,0,20,0);
			//gridSplitter_Left.Visibility = System.Windows.Visibility.Collapsed;
			gridLength = columnDefinition.Width;
			var animation = new GridLengthAnimation
			{
				To = new GridLength(0),
				Duration = new Duration(TimeSpan.FromSeconds(.25))
			};
			columnDefinition.BeginAnimation(ColumnDefinition.WidthProperty, animation);
		}

		void ExpandRow(RowDefinition rowDefinition, ref GridLength gridLength, GridSplitter gridSplitter)
		{
			rowDefinition.MinHeight = marginExpanded;

			var animation = new GridLengthAnimation
			{
				From = rowDefinition.Height,
				To = gridLength,
				Duration = new Duration(TimeSpan.FromSeconds(.25)),
				FillBehavior = FillBehavior.Stop
			};

			animation.Completed += ((sender, e) =>
			{
				if (gridSplitter != null)
				{
					gridSplitter.IsEnabled = true;
				}
			});
			rowDefinition.BeginAnimation(RowDefinition.HeightProperty, animation);
		}

		void ContractRow(RowDefinition rowDefinition, ref GridLength gridLength, GridSplitter gridSplitter)
		{
			rowDefinition.MinHeight = marginContracted;

			if (gridSplitter != null)
			{
				gridSplitter.IsEnabled = false;
			}

			gridLength = rowDefinition.Height;
			var animation = new GridLengthAnimation
			{
				To = new GridLength(0),
				Duration = new Duration(TimeSpan.FromSeconds(.25))
			};
			rowDefinition.BeginAnimation(RowDefinition.HeightProperty, animation);
		}

		#endregion

		#region Hide and show regions based on whether they are populated
		void UpdateAllRegionDimensions()
		{
			UpdateRegionVisibility(tabControl_Right, gridSplitter_Right, columnDefinition_Right, border_Right);
			UpdateRegionVisibility(tabControl_Left, gridSplitter_Left, columnDefinition_Left, border_Left);
			UpdateRegionVisibility(tabControl_Bottom, gridSplitter_Bottom, rowDefinition_OutputDisplay, border_Bottom);
		}

		void OnTabControl_Right_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			UpdateRegionVisibility(tabControl_Right, gridSplitter_Right, columnDefinition_Right, border_Right);
			var content = tabControl_Right.SelectedContent as UIElement;
			if (content != null)
			{
				content.Focus();
			}
		}

		void OnTabControl_Left_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			UpdateRegionVisibility(tabControl_Left, gridSplitter_Left, columnDefinition_Left, border_Left);
			var content = tabControl_Left.SelectedContent as UIElement;
			if (content != null)
			{
				content.Focus();
			}
		}

		void OnTabControl_Bottom_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			UpdateRegionVisibility(tabControl_Bottom, gridSplitter_Bottom, rowDefinition_OutputDisplay, border_Bottom);
			var content = tabControl_Bottom.SelectedContent as UIElement;
			if (content != null)
			{
				content.Focus();
			}
		}

		void UpdateRegionVisibility(TabControl tabControl, GridSplitter gridSplitter,
			RowDefinition rowDefinition, Border border)
		{
			var itemCount = tabControl.Items.Count;
			if (itemCount < 1)
			{
				rowDefinition.MaxHeight = 0;
				rowDefinition.MinHeight = marginContracted;
				gridSplitter.Visibility = Visibility.Collapsed;
				border.Visibility = Visibility.Collapsed;
			}
			else if (itemCount == 1)
			{
				rowDefinition.MaxHeight = double.MaxValue;
				rowDefinition.MinHeight = marginExpanded;
				gridSplitter.Visibility = Visibility.Visible;
				border.Visibility = Visibility.Visible;
			}
		}

		void UpdateRegionVisibility(TabControl tabControl, GridSplitter gridSplitter,
			ColumnDefinition columnDefinition, Border border)
		{
			var itemCount = tabControl.Items.Count;
			if (itemCount < 1)
			{
				columnDefinition.MaxWidth = 0;
				columnDefinition.MinWidth = marginContracted;
				gridSplitter.Visibility = Visibility.Collapsed;
				border.Visibility = Visibility.Collapsed;
			}
			else if (itemCount == 1)
			{
				columnDefinition.MaxWidth = double.MaxValue;
				columnDefinition.MinWidth = marginExpanded;
				gridSplitter.Visibility = Visibility.Visible;
				border.Visibility = Visibility.Visible;
			}
		}
		#endregion
	}
}
